package it.ap.sa.core.utils;

import java.text.DecimalFormat;

import org.apache.commons.logging.Log;
import org.slf4j.Logger;
import org.springframework.util.StopWatch;

/**
 * @author Alessandro Paolillo
 */
public abstract class LogUtil {

	/**
	 * DECIMAL FORMAT PER INTERI
	 */
	private static final DecimalFormat LOG_INT_DECIMAL_FORMAT = new DecimalFormat("#,##0");
	/**
	 * VALORE DA RESTITUIRE COME DEFAULT PER LA FORMATTAZIONE DI INTERI IN CASO DI WRAPPER NULL
	 */
	private static final String DEFAULT_INT_VALUE_FOR_NULL = null;

	/**
	 * @author Alessandro Paolillo
	 */
	public static StopWatch startStopWatch(String id){
		StopWatch stopWatch = new SmStopWatch(id);
		stopWatch.start();
		return stopWatch;
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public static StopWatch startStopWatch(String id,Log log){
		StopWatch stopWatch = startStopWatch(id);
		log.info("Start " + id);
		return stopWatch;
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public static StopWatch startStopWatch(String id,Logger logger){
		StopWatch stopWatch = startStopWatch(id);
		logger.info("Start " + id);
		return stopWatch;
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public static String endStopWatch(StopWatch stopWatch){
		stopWatch.stop();
		return stopWatch.shortSummary();
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public static void endStopWatch(StopWatch stopWatch, Log log){
		log.info(endStopWatch(stopWatch));
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public static void endStopWatch(StopWatch stopWatch, Logger logger){
		logger.info(endStopWatch(stopWatch));
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public static String formatByte(byte byteNumber){
		return byteNumber + "";
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public static String formatShort(short shortNumber){
		return LOG_INT_DECIMAL_FORMAT.format(shortNumber);
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public static String formatInt(int intNumber){
		return LOG_INT_DECIMAL_FORMAT.format(intNumber);
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public static String formatLong(long longNumber){
		return LOG_INT_DECIMAL_FORMAT.format(longNumber);
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public static String formatByte(Byte byteNumber){
		return byteNumber == null ? DEFAULT_INT_VALUE_FOR_NULL : formatByte(byteNumber.byteValue());
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public static String formatShort(Short shortNumber){
		return shortNumber == null ? DEFAULT_INT_VALUE_FOR_NULL : formatShort(shortNumber.shortValue());
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public static String formatInt(Integer intNumber){
		return intNumber == null ? DEFAULT_INT_VALUE_FOR_NULL : formatInt(intNumber.intValue());
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public static String formatLong(Long longNumber){
		return longNumber == null ? DEFAULT_INT_VALUE_FOR_NULL : formatLong(longNumber.longValue());
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public static void logMemory(Logger logger){
		String[] memoryState = memoryState();
		for(String item : memoryState)
			logger.info(item);
	}
	/**
	 * @author Alessandro Paolillo
	 */
	public static void logMemory(Log log){
		String[] memoryState = memoryState();
		for(String item : memoryState)
			log.info(item);
	}
	/**
	 * @author Alessandro Paolillo
	 */
	private static String[] memoryState(){
		Runtime       runtime     = Runtime.getRuntime();
		StringBuilder freeMemory  = new StringBuilder(formatLong(runtime.freeMemory ()));
		StringBuilder totalMemory = new StringBuilder(formatLong(runtime.totalMemory()));
		StringBuilder maxMemory   = new StringBuilder(formatLong(runtime.maxMemory  ()));
		int           maxLength   = maxMemory.length();

		while(freeMemory.length() < maxLength)
			freeMemory.insert(0, " ");

		while(totalMemory.length() < maxLength)
			totalMemory.insert(0, " ");

		return new String[]{"Free  Memory = " + freeMemory  + " bytes"
		                   ,"Total Memory = " + totalMemory + " bytes"
		                   ,"Max   Memory = " + maxMemory   + " bytes"
		                   };
	}

}
